﻿using Aliyun.OSS;
using Aliyun.OSS.Util;
using MiniFox.Components;
using MiniFox.Platform.File.Models;
using MiniFox.Platform.File.Services;
using OSS.AliyunCloud.Configurations;
using System.Xml.Linq;

namespace OSS.AliyunCloud
{
    /// <summary>
    /// 
    /// </summary>
    public class OssManagerService : Component
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        public OssManagerService(string name)
        {
            BucketName = name;
        }
        /// <summary>
        /// bucket name
        /// </summary>
        public string BucketName { get; }
        /// <summary>
        /// 
        /// </summary>
        [AutoConfigure]
        public virtual OssConfiguration OssConfig
        {
            get;
            set;
        }

        OssClient _ossClient;
        /// <summary>
        /// 
        /// </summary>
        protected virtual OssClient Client
        {
            get
            {
                if (_ossClient == null)
                {
                    var setting = OssConfig.BucketSettings[BucketName];
                    // 创建OssClient实例。
                    _ossClient = new OssClient(setting.Endpoint, setting.AccessKeyId, setting.AccessKeySecret);
                    _ossClient.SetRegion(setting.Region);
                }
                return _ossClient;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileData"></param>
        public void Load(FileData fileData)
        {
            try
            {
                var obj = Client.GetObject(BucketName, fileData.FullName.TrimStart('/'));
                using (var ms = new MemoryStream())
                {
                    obj.Content.CopyTo(ms);
                    fileData.Data = ms.ToArray();
                }
            }
            catch (Exception ex)
            {
                WriteErrorLog(ex.Message, ex);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileData"></param>
        /// <returns></returns>
        public async Task LoadAsync(FileData fileData)
        {
            try
            {
                var obj = Client.GetObject(BucketName, fileData.FullName.TrimStart('/'));
                await using (var ms = new MemoryStream())
                {
                    await obj.Content.CopyToAsync(ms);
                    fileData.Data = ms.ToArray();
                }
            }
            catch (Exception ex)
            {
                WriteErrorLog(ex.Message, ex);
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileData"></param>
        public void Remove(FileData fileData)
        {
            try
            {
                var result = Client.DeleteObject(BucketName, fileData.FullName.TrimStart('/'));

                if (result.HttpStatusCode != System.Net.HttpStatusCode.OK)
                    WriteInfoLog(result.HttpStatusCode.ToString());
            }
            catch (Exception ex)
            {
                WriteErrorLog(ex.Message, ex);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileData"></param>
        public void Save(FileData fileData)
        {
            try
            {
                using (var ms = new MemoryStream(fileData.Data))
                {
                    var objectMeta = new ObjectMetadata
                    {
                        // 计算MD5。
                        ContentMd5 = OssUtils.ComputeContentMd5(ms, ms.Length)
                    };
                    // 上传文件。
                    var result = Client.PutObject(BucketName, fileData.FullName.TrimStart('/'), ms, objectMeta);

                    if (result.HttpStatusCode != System.Net.HttpStatusCode.OK)
                        WriteInfoLog(result.HttpStatusCode.ToString());
                }
            }
            catch (Exception ex)
            {
                WriteErrorLog(ex.Message, ex);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileData"></param>
        /// <returns></returns>
        public async Task SaveAsync(FileData fileData)
        {
            try
            {
                await using (var ms = new MemoryStream(fileData.Data))
                {
                    var objectMeta = new ObjectMetadata
                    {
                        // 计算MD5。
                        ContentMd5 = OssUtils.ComputeContentMd5(ms, ms.Length)
                    };
                    // 上传文件。
                    var result = Client.PutObject(BucketName, fileData.FullName.TrimStart('/'), ms, objectMeta);

                    if (result.HttpStatusCode != System.Net.HttpStatusCode.OK)
                        WriteInfoLog(result.HttpStatusCode.ToString());
                }
            }
            catch (Exception ex)
            {
                WriteErrorLog(ex.Message, ex);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public ObjectListing GetObjects(string path)
        {
            var result = Client.ListObjects(BucketName, $"{path.Trim('/')}/");
            //var total = result.ObjectSummaries.Count();
            //response.List = result.ObjectSummaries.Skip(response.Start).Take(response.Size).Select(summary => new { url = $"/{summary.Key.Trim()}" });
            return result;
        }
    }



}
